package nancal.mp.mvc.dev2


import io.swagger.annotations.Api
import nancal.mp.db.mongo.mor
import nbcp.base.annotation.*

import nbcp.base.comm.*
import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.base.utils.StringUtil
import nbcp.mvc.sys.setDownloadFileName
import nbcp.myoql.db.db
import nbcp.myoql.db.mongo.*
import nbcp.myoql.db.mongo.base.MongoColumnName
import org.bson.Document
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import javax.servlet.http.HttpServletResponse

/**
 * Created by CodeGenerator at 2021-04-11 23:42:19
 */
@Api(description = "Mongo数据连接", tags = arrayOf("MongoConnection"))
@RestController
@RequestMapping("/dev/mongo")
class MongoToolController {

    @PostMapping("/group-tables/{id}")
    fun tables(
        @Require id: String
    ): ApiResult<Map<String, List<String>>> {
        var conn = mor.dev.mongoConnection.queryById(id).toEntity().must().elseThrow { "找不到数据库连接" }
        var t = db.mongo.getMongoTemplateByUri(conn.connectionUri)!!;
        var list = t.db.listCollectionNames().toList();
        var data = list.groupBy { StringUtil.getUnderlineCase(it).split("_").first() }
        return ApiResult.of(data);
    }


    data class WhereExpression(
        var column: String = "",
        var op: String = "",
        var value: String = ""
    )


    @PostMapping("/get-data/{id}")
    fun viewMongo(
        @Require id: String,
        @Require table: String,
        wheres: List<WhereExpression>,
        @org.springframework.web.bind.annotation.RequestBody query: PagerModel<Any?>,
    ): ListResult<Document> {
        var conn = mor.dev.mongoConnection.queryById(id).toEntity().must().elseThrow { "找不到数据库连接" }
        query.take = Math.min(query.take, 25)
        return getData(conn.connectionUri, table, wheres, query);
    }

    fun getData(
        @Require connectionUri: String,
        @Require table: String,
        wheres: List<WhereExpression>,
        queryModel: PagerModel<Any?>,
    ): ListResult<Document> {

        val ent = db.mongo.dynamicEntity(table)

        usingScope(MongoTemplateScope(db.mongo.getMongoTemplateByUri(connectionUri)!!)) {

            var query = MongoQueryClip(ent);

            wheres.forEach { where ->
                if (where.column.isNullOrEmpty()) {
                    return@forEach
                }
                var column = MongoColumnName(where.column)
                var criteria: Criteria? = null;

                if (where.op == ">") {
                    criteria = (column greaterThan where.value)
                } else if (where.op == ">=") {
                    criteria = column greaterThanEquals where.value
                } else if (where.op == "<") {
                    criteria = column lessThan where.value
                } else if (where.op == "<=") {
                    criteria = column lessThanEquals where.value
                } else if (where.op == "!=") {
                    criteria = column mongoNotEquals where.value
                } else if (where.op == "like") {
                    criteria = column mongoLike where.value
                } else {
                    criteria = column mongoEquals where.value
                }

                query.where(criteria);
            }

            var list = query.withPager(queryModel)
                .orderByDesc { MongoColumnName("_id") }
                .toMapList()
            return ListResult.of(list);
        }
    }

    @PostMapping("/export/{id}")
    fun exportMongo(
        @Require id: String,
        @Require table: String,
        wheres: List<WhereExpression>,
        @org.springframework.web.bind.annotation.RequestBody queryModel: PagerModel<Any?>,
        response: HttpServletResponse
    ) {
        var conn = mor.dev.mongoConnection.queryById(id).toEntity().must().elseThrow { "找不到数据库连接" }
        val ent = db.mongo.dynamicEntity(table)

        usingScope(MongoTemplateScope(db.mongo.getMongoTemplateByUri(conn.connectionUri)!!)) {

            var query = MongoQueryClip(ent);

            wheres.forEach { where ->
                query.where {

                    var column = MongoColumnName(where.column)

                    if (where.op == ">") {
                        return@where column greaterThan where.value
                    } else if (where.op == ">=") {
                        return@where column greaterThanEquals where.value
                    } else if (where.op == "<") {
                        return@where column lessThan where.value
                    } else if (where.op == "<=") {
                        return@where column lessThanEquals where.value
                    } else if (where.op == "!=") {
                        return@where column mongoNotEquals where.value
                    } else if (where.op == "like") {
                        return@where column mongoLike where.value
                    }

                    return@where column mongoEquals where.value
                }
            }

            var content =
                query.withPager(queryModel)
                    .toMapList()
                    .map { it.ToJson() }
                    .joinToString("\n");

            response.setDownloadFileName(table + ".dat");
            response.outputStream.write(content.toByteArray())
        }
    }


    @PostMapping("/import/{id}")
    fun importMongo(
        file: MultipartFile,
        id: String
    ): ApiResult<JsonMap> {
        var conn = mor.dev.mongoConnection.queryById(id).toEntity().must().elseThrow { "找不到数据库连接" }

        var fileName = file.originalFilename;
        if (!fileName.endsWith(".dat")) {
            return ApiResult.error("必须是 .dat 结尾")
        }

        var lines = file.inputStream.readContentString()
            .split("\n")
            .filter { it.HasValue }
            .map { it.FromJson<MongoDynamicEntity>()!! }

        if (lines.any() == false) {
            return ApiResult.error("找不到数据")
        }

        var tableName = fileName.Slice(0, -4);

        val ent = MongoDynamicMetaEntity(tableName)
        var count = 0;
        var errorCount = 0;


        usingScope(MongoTemplateScope(db.mongo.getMongoTemplateByUri(conn.connectionUri)!!)) {
            lines.forEach {
                var ret =
                    MongoSetEntityUpdateClip(ent, it).whereColumn { MongoColumnName("id") }
                        .doubleExecSave();
                count++;
                if (ret == 0) {
                    errorCount++;
                }
            }
        }


        return ApiResult.of(JsonMap("count" to count, "errorCount" to errorCount))
    }

    @PostMapping("/delete-id/{connId}")
    fun deleteId(
        @Require connId: String,
        @Require table: String,
        @Require rowId: String
    ): JsonResult {
        var conn = mor.dev.mongoConnection.queryById(connId).toEntity().must().elseThrow { "找不到数据库连接" }
        val ent = db.mongo.dynamicEntity(table)

        usingScope(MongoTemplateScope(db.mongo.getMongoTemplateByUri(conn.connectionUri)!!)) {

            var delete = MongoDeleteClip(ent);
            delete.where(MongoColumnName("_id") mongoEquals rowId)
            delete.exec();
        }
        return JsonResult();
    }
}